/*****************************************************************************
 * Copyright (C) Stacy Curl. All rights reserved.                            *
 * ------------------------------------------------------------------------- *
 * The software in this package is published under the terms of the BSD      *
 * style license a copy of which has been included with this distribution in *
 * the LICENSE.txt file.                                                     *
 *****************************************************************************/
package picounit.features.verify.constraint;

import picounit.features.aggregate_exception.Thrower;
import picounit.features.mocking.Verifiable;
import picounit.features.verify.Evaluator;
import picounit.features.verify.NullReasonCapturer;
import picounit.verify.ReasonCapturer;
import picounit.verify.constraint.Constraint;
import junit.framework.AssertionFailedError;

public class UnconditionalEvaluator implements Evaluator {
	private final Verifiable verifiable;
	private final Thrower thrower;

	private String reason;

	private Object value;

	public UnconditionalEvaluator(Thrower thrower, Verifiable verifiable) {
		this.thrower = thrower;
		this.verifiable = verifiable;
	}
	
	public void setValue(Object value) {
		this.value = value;
	}
	
	public Object getValue() {
		return value;
	}

	public void setReason(String reason) {
		this.reason = reason;
	}

	public ReasonCapturer evaluate(Constraint constraint) {
		return evaluate(constraint, Stringer.DEFAULT);
	}

	@SuppressWarnings("unchecked")
	public ReasonCapturer evaluate(Constraint constraint, Stringer stringer) {
		try {
			verifiable.verify();

			if (!constraint.evaluate(value)) {
				thrower.errorEvent(new AssertionFailedError((prefix() + "<" + stringer.toString(value) +
					"> " + constraint.describeFailure())));
			}
		}
		finally {
			reason = null;
			value = null;
		}

		return NullReasonCapturer.INSTANCE;
	}

	private String prefix() {
		return reason == null ? "" : reason + ", ";
	}
}
